package com.jl.card.parse;

public class TerminalProfileStructure {

	public static final String CLASS_A = "A";
	public static final String CLASS_B = "B";
	public static final String CLASS_C = "C";
	public static final String CLASS_D = "D";
	public static final String CLASS_E = "E";
	public static final String CLASS_F = "F";
	public static final String CLASS_G = "G";
	public static final String CLASS_H = "H";
	public static final String CLASS_I = "I";
	public static final String CLASS_J = "J";
	public static final String CLASS_K = "K";
	public static final String CLASS_L = "L";
	public static final String CLASS_M = "M";
	public static final String CLASS_N = "N";
	public static final String CLASS_O = "O";
	public static final String CLASS_P = "P";

	private byte[] data;

	public TerminalProfileStructure(byte[] data) {
		this.data = data.clone();
	}

	/**
	 * 
	 * @param index
	 *            the index of data(1-30)
	 * @param b
	 *            the bit of data[index](1-8)
	 * @return
	 */
	public String getName(int index, int b) {
		if (index < 0 || b > 8 || b < 1) {
			throw new IndexOutOfBoundsException();
		}
		String res = "RFU";
		index--;
		switch (index) {
		case 0:
			switch (b) {
			case 1:
				res = "Profile download";
				break;
			case 2:
				res = "Reserved by 3GPP (SMS-PP data download)";
				break;
			case 3:
				res = "Reserved by 3GPP (Cell Broadcast data download)";
				break;
			case 4:
				res = "Menu selection";
				break;
			case 5:
				res = "Reserved by 3GPP (SMS-PP data download)";
				break;
			case 6:
				res = "Timer expiration";
				break;
			case 7:
				res = "Reserved by 3GPP (USSD string data object support in Call Control by USIM)";
				break;
			case 8:
				res = "Call Control by NAA";
				break;
			}
			break;
		case 1:
			switch (b) {
			case 1:
				res = "Command result";
				break;
			case 2:
				res = "Call Control by NAA";
				break;
			case 3:
				res = "Call Control by NAA";
				break;
			case 4:
				res = "reserved by 3GPP (MO short message control support)";
				break;
			case 5:
				res = "Call Control by NAA";
				break;
			case 6:
				res = "UCS2 Entry supported";
				break;
			case 7:
				res = "UCS2 Display supported";
				break;
			case 8:
				res = "Display Text";
				break;
			}
			break;
		case 2:
			switch (b) {
			case 1:
				res = "Proactive UICC: DISPLAY TEXT";
				break;
			case 2:
				res = "Proactive UICC: GET INKEY";
				break;
			case 3:
				res = "Proactive UICC: GET INPUT";
				break;
			case 4:
				res = "Proactive UICC: MORE TIME";
				break;
			case 5:
				res = "Proactive UICC: PLAY TONE";
				break;
			case 6:
				res = "Proactive UICC: POLL INTERVAL";
				break;
			case 7:
				res = "Proactive UICC: POLLING OFF";
				break;
			case 8:
				res = "Proactive UICC: REFRESH";
				break;
			}
			break;
		case 3:
			switch (b) {
			case 1:
				res = "Proactive UICC: SELECT ITEM";
				break;
			case 2:
				res = "Reserved by 3GPP (Proactive UICC: SEND SHORT MESSAGE with 3GPP-SMS-TPDU)";
				break;
			case 3:
				res = "Reserved by 3GPP (Proactive UICC: SEND SS)";
				break;
			case 4:
				res = "Reserved by 3GPP (Proactive UICC: SEND USSD)";
				break;
			case 5:
				res = "Proactive UICC: SET UP CALL";
				break;
			case 6:
				res = "Proactive UICC: SET UP MENU";
				break;
			case 7:
				res = "Proactive UICC: PROVIDE LOCAL INFORMATION (MCC, MNC, LAC, Cell ID & IMEI)";
				break;
			case 8:
				res = "Proactive UICC: PROVIDE LOCAL INFORMATION (NMR)";
				break;
			}
			break;
		case 4:
			switch (b) {
			case 1:
				res = "Proactive UICC: SET UP EVENT LIST";
				break;
			case 2:
				res = "Event: MT call";
				break;
			case 3:
				res = "Event: Call connected";
				break;
			case 4:
				res = "Event: Call disconnected";
				break;
			case 5:
				res = "Event: Location status";
				break;
			case 6:
				res = "Event: User activity";
				break;
			case 7:
				res = "Event: Idle screen available";
				break;
			case 8:
				res = "Event: Card reader status";
				break;
			}
			break;
		case 5:
			switch (b) {
			case 1:
				res = "Event: Language selection";
				break;
			case 2:
				res = "Event: Browser Termination";
				break;
			case 3:
				res = "Event: Data available";
				break;
			case 4:
				res = "Event: Channel status";
				break;
			case 5:
				res = "Event: Access Technology Change";
				break;
			case 6:
				res = "Event: Display parameters changed";
				break;
			case 7:
				res = "Event: Local Connection";
				break;
			case 8:
				res = "Event: Network Search Mode Change";
				break;
			}
			break;
		case 6:
			switch (b) {
			case 1:
				res = "Proactive UICC: POWER ON CARD";
				break;
			case 2:
				res = "Proactive UICC: POWER OFF CARD";
				break;
			case 3:
				res = "Proactive UICC: PERFORM CARD APDU";
				break;
			case 4:
				res = "Proactive UICC: GET READER STATUS (Card reader status)";
				break;
			case 5:
				res = "Proactive UICC: GET READER STATUS (Card reader identifier)";
				break;
			case 6:
				break;
			case 7:
				break;
			case 8:
				break;
			}
			break;
		case 7:
			switch (b) {
			case 1:
				res = "Proactive UICC: TIMER MANAGEMENT (start, stop)";
				break;
			case 2:
				res = "Proactive UICC: TIMER MANAGEMENT (get current value)";
				break;
			case 3:
				res = "Proactive UICC: PROVIDE LOCAL INFORMATION (date, time and time zone)";
				break;
			case 4:
				res = "GET INKEY";
				break;
			case 5:
				res = "SET UP IDLE MODE TEXT";
				break;
			case 6:
				res = "RUN AT COMMAND (i.e. class \"b\" is supported)";
				break;
			case 7:
				res = "SETUP CALL";
				break;
			case 8:
				res = "Call Control by NAA";
				break;
			}
			break;
		case 8:
			switch (b) {
			case 1:
				res = "DISPLAY TEXT";
				break;
			case 2:
				res = "SEND DTMF command";
				break;
			case 3:
				res = "Proactive UICC: PROVIDE LOCAL INFORMATION (NMR)";
				break;
			case 4:
				res = "Proactive UICC: PROVIDE LOCAL INFORMATION (language)";
				break;
			case 5:
				res = "Reserved by 3GPP (Proactive UICC: PROVIDE LOCAL INFORMATION, Timing Advance)";
				break;
			case 6:
				res = "Proactive UICC: LANGUAGE NOTIFICATION";
				break;
			case 7:
				res = "Proactive UICC: LAUNCH BROWSER";
				break;
			case 8:
				res = "Proactive UICC: PROVIDE LOCAL INFORMATION (Access Technology)";
				break;
			}
			break;
		case 9:
			switch (b) {
			case 1:
				res = "Soft keys support for SELECT ITEM";
				break;
			case 2:
				res = "Soft Keys support for SET UP MENU";
				break;
			case 3:
				break;
			case 4:
				break;
			case 5:
				break;
			case 6:
				break;
			case 7:
				break;
			case 8:
				break;
			}
			break;
		case 10:
			res = "Maximum number of soft keys available";
			break;
		case 11:
			switch (b) {
			case 1:
				res = "Proactive UICC: OPEN CHANNEL";
				break;
			case 2:
				res = "Proactive UICC: CLOSE CHANNEL";
				break;
			case 3:
				res = "Proactive UICC: RECEIVE DATA";
				break;
			case 4:
				res = "Proactive UICC: SEND DATA";
				break;
			case 5:
				res = "Proactive UICC: GET CHANNEL STATUS";
				break;
			case 6:
				res = "Proactive UICC: SERVICE SEARCH";
				break;
			case 7:
				res = "Proactive UICC: GET SERVICE INFORMATION";
				break;
			case 8:
				res = "Proactive UICC: DECLARE SERVICE";
				break;
			}
			break;
		case 12:
			switch (b) {
			case 1:
				res = "CSD";
				break;
			case 2:
				res = "GPRS";
				break;
			case 3:
				res = "Bluetooth";
				break;
			case 4:
				res = "IrDA";
				break;
			case 5:
				res = "RS232";
				break;
			case 6:
			case 7:
			case 8:
				res = "bit6-bit8 Number of channels supported by terminal";
				break;
			}
			break;
		case 13:
			switch (b) {
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
				res = "bit1-bit5 Number of characters supported down the terminal display";
				break;
			case 6:
				res = "No display capability (i.e class \"ND\" is indicated)";
				break;
			case 7:
				res = "No keypad available (i.e. class \"NK\" is indicated)";
				break;
			case 8:
				res = "Screen Sizing Parameters supported";
				break;
			}
			break;
		case 14:
			switch (b) {
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
				res = "bit1-bit7 Number of characters supported across the terminal  display";
				break;
			case 8:
				res = "Variable size fonts";
				break;
			}
			break;
		case 15:
			switch (b) {
			case 1:
				res = "Display can be resized";
				break;
			case 2:
				res = "Text Wrapping supported";
				break;
			case 3:
				res = "Text Scrolling supported";
				break;
			case 4:
				res = "Text Attributes supported";
				break;
			case 5:
				break;
			case 6:
			case 7:
			case 8:
				res = "bit6-bit8 Width reduction when in a menu";
				break;
			}
			break;
		case 16:
			switch (b) {
			case 1:
				res = "TCP, UICC in client mode, remote connection";
				break;
			case 2:
				res = "UDP, UICC in client mode, remote connection";
				break;
			case 3:
				res = "TCP, UICC in server mode";
				break;
			case 4:
				res = "TCP, UICC in client mode, local connection (i.e. class \"k\" is supported)";
				break;
			case 5:
				res = "UDP, UICC in client mode, local connection (i.e.  class \"k\" is supported)";
				break;
			case 6:
				break;
			case 7:
				res = "Reserved by 3GPP (E-UTRAN (if class \"e\" is  supported))";
				break;
			case 8:
				res = "Reserved by 3GPP (HSDPA (if class \"e\" is  supported))";
				break;
			}
			break;
		case 17:
			switch (b) {
			case 1:
				res = "Proactive UICC: DISPLAY TEXT (Variable Time out)";
				break;
			case 2:
				res = "Proactive UICC: GET INKEY (help is supported while  waiting for immediate response or variable timeout)";
				break;
			case 3:
				res = "USB";
				break;
			case 4:
				res = "Proactive UICC: GET INKEY (Variable Timeout)";
				break;
			case 5:
				res = "Proactive UICC: PROVIDE LOCAL INFORMATION (ESN)";
				break;
			case 6:
				res = "Reserved by 3GPP (Call control on GPRS)";
				break;
			case 7:
				res = "Proactive UICC: PROVIDE LOCAL INFORMATION (IMEISV)";
				break;
			case 8:
				res = "Proactive UICC: PROVIDE LOCAL INFORMATION (Search  Mode change)";
				break;
			}
			break;
		case 18:
			switch (b) {
			case 1:
			case 2:
			case 3:
			case 4:
				res = "Reserved by TIA/EIA-136 [25] (Protocol Version support)";
				break;
			case 5:
				break;
			case 6:
				break;
			case 7:
				break;
			case 8:
				break;
			}
			break;
		case 19:
			res = "Reserved by TIA/EIA/IS-820 [17]";
			break;
		case 20:
			switch (b) {
			case 1:
				res = "WML";
				break;
			case 2:
				res = "XHTML";
				break;
			case 3:
				res = "HTML";
				break;
			case 4:
				res = "CHTML";
				break;
			case 5:
				break;
			case 6:
				break;
			case 7:
				break;
			case 8:
				break;
			}
			break;
		case 21:
			switch (b) {
			case 1:
				res = "Reserved by 3GPP (Support of UTRAN PS with extended  parameters)";
				break;
			case 2:
				res = "Proactive UICC: PROVIDE LOCAL INFORMATION(battery  state), (i.e. class \"g\" is supported)";
				break;
			case 3:
				res = "Proactive UICC: PLAY TONE (Melody tones and Themed  tones supported)";
				break;
			case 4:
				res = "Multi-media Calls in SET UP CALL (if class h  supported)";
				break;
			case 5:
				res = "Reserved by 3GPP (Toolkit-initiated GBA)";
				break;
			case 6:
				res = "Proactive UICC: RETRIEVE MULTIMEDIA MESSAGE (if  class \"j\" is supported)";
				break;
			case 7:
				res = "Proactive UICC: SUBMIT MULTIMEDIA MESSAGE (if class  \"j\" is supported)";
				break;
			case 8:
				res = "Proactive UICC: DISPLAY MULTIMEDIA MESSAGE (if  class \"j\" is supported)";
				break;
			}
			break;
		case 22:
			switch (b) {
			case 1:
				res = "Proactive UICC: SET FRAMES (i.e. class \"i\" is  supported)";
				break;
			case 2:
				res = "Proactive UICC: GET FRAMES STATUS (i.e. class \"i\" is  supported)";
				break;
			case 3:
				res = "MMS notification download (if class \"j\" is  supported)";
				break;
			case 4:
				res = "Alpha Identifier in REFRESH command supported by  terminal";
				break;
			case 5:
				res = "Reserved by 3GPP (Geographical Location Reporting  (if class \"n\" is supported))";
				break;
			case 6:
				res = "Proactive UICC: PROVIDE LOCAL INFORMATION (MEID)";
				break;
			case 7:
				res = "Reserved by 3GPP (Proactive UICC: PROVIDE LOCAL  INFORMATION (NMR(UTRAN)))";
				break;
			case 8:
				res = "Reserved by 3GPP (USSD Data download and application  mode)";
				break;
			}
			break;
		case 23:
			switch (b) {
			case 1:
			case 2:
			case 3:
			case 4:
				res = "bit1-bit4 Maximum number of frames supported (including  frames created in existing frames)";
				break;
			case 5:
				break;
			case 6:
				break;
			case 7:
				break;
			case 8:
				break;
			}
			break;
		case 24:
			switch (b) {
			case 1:
				res = "Event: Browsing status";
				break;
			case 2:
				res = "Event: MMS Transfer status (if class \"j\" is  supported)";
				break;
			case 3:
				res = "Event: Frame Parameters changed (i.e. class \"i\" is  supported)";
				break;
			case 4:
				res = "Reserved by 3GPP (Event: I-WLAN Access status (if  class \"e\" is supported))";
				break;
			case 5:
				res = "Reserved by 3GPP (Event Network Rejection)";
				break;
			case 6:
				res = "Event: HCI connectivity event (i.e. class \"m\" is  supported)";
				break;
			case 7:
				res = "Reserved by 3GPP (E-UTRAN support in Event Network  Rejection)";
				break;
			case 8:
				res = "Multiple access technologies supported in Event  Access Technology Change and PROVIDE LOCALINFORMATION ";
				break;
			}
			break;
		case 25:
			break;
		case 26:
			break;
		case 27:
			switch (b) {
			case 1:
				res = "Alignment left supported by Terminal";
				break;
			case 2:
				res = "Alignment centre supported by Terminal";
				break;
			case 3:
				res = "Alignment right supported by Terminal";
				break;
			case 4:
				res = "Font size normal supported by Terminal";
				break;
			case 5:
				res = "Font size large supported by Terminal";
				break;
			case 6:
				res = "Font size small supported by Terminal";
				break;
			case 7:
				break;
			case 8:
				break;
			}
			break;
		case 28:
			switch (b) {
			case 1:
				res = "Style normal supported by Terminal";
				break;
			case 2:
				res = "Style bold supported by Terminal";
				break;
			case 3:
				res = "Style italic supported by Terminal";
				break;
			case 4:
				res = "Style underlined supported by Terminal";
				break;
			case 5:
				res = "Style strikethrough supported by Terminal";
				break;
			case 6:
				res = "Style text foreground colour supported by Terminal";
				break;
			case 7:
				res = "Style text background colour supported by Terminal";
				break;
			case 8:
				break;
			}
			break;
		case 29:
			switch (b) {
			case 1:
				res = "Reserved by 3GPP (I-WLAN bearer support (if class  \"e\" is supported))";
				break;
			case 2:
				res = "Reserved by 3GPP (Proactive UICC: PROVIDE LOCAL  INFORMATION (WSID of the current I-WLAN connection))";
				break;
			case 3:
				res = "TERMINAL APPLICATIONS (i.e. class \"k\" is supported)";
				break;
			case 4:
				res = "Reserved by 3GPP (Steering of Roaming REFRESH  support)";
				break;
			case 5:
				res = "Proactive UICC: ACTIVATE (i.e class \"l\" is  supported)";
				break;
			case 6:
				res = "Reserved for 3GPP (Proactive UICC: GEOGRAPHICAL  LOCATION REQUEST (if class \"n\" is supported))";
				break;
			case 7:
				res = "Proactive UICC: PROVIDE LOCAL INFORMATION  (Broadcast Network Information) (i.e. class \"o\" is supported)";
				break;
			case 8:
				res = "Reserved by 3GPP (Steering of Roaming for I-WLAN  REFRESH support)";
				break;
			}
			break;
		default:
			break;
		}
		return res;
	}

	/**
	 * 
	 * @param index
	 *            the index of data(1-30)
	 * @param b
	 *            the bit of data[index](1-8)
	 * @return
	 */
	public boolean isSupportedByTerminal(int index, int b) {
		if(index > data.length){
			return false;
		}
		index--;
		return !((data[index] & (1 << (b - 1))) == 0);
	}

	public int getNumberOfChannel() {
		return (data[12] >> 5) & 0b0000_0111;
	}

	public int getNumberOfCharactersDown() {
		return (data[13] & 0b0001_1111);
	}

	public int getNumberOfCharactersAcross() {
		return (data[14] & 0b0111_1111);
	}

	public int getWidthReductionInMenu() {
		return (data[15] >> 5) & 0b0000_0111;
	}

	public int getMaximumNumberOfFrames() {
		return (data[23] & 0b0000_1111);
	}

	/**
	 * check the _class is all support by terminal,if all support then return true,else return false.
	 * @param _class
	 * @return
	 */
	public boolean isSupportClass(String _class) {
		for(char ch : _class.toCharArray()){
			if(Character.isSpaceChar(ch)){
				continue;
			}
			if(!isSupportClass(ch)){
				return false;
			}
		}
		return true;
	}
	
	public boolean isSupportClass(char ch){
		ch = Character.toUpperCase(ch);
		String _class = ch + "";
		switch (_class.trim().toUpperCase()) {
		case CLASS_A:
			return this.isSupportedByTerminal(7, 4);
		case CLASS_B:
			return this.isSupportedByTerminal(8, 6);
		case CLASS_C:
			return this.isSupportedByTerminal(9, 7);
		case CLASS_D:
			return this.isSupportedByTerminal(10, 1);
		case CLASS_E:
			return this.isSupportedByTerminal(12, 1);
		case CLASS_F:
			return this.isSupportedByTerminal(12, 6);
		case CLASS_G:
			return this.isSupportedByTerminal(4, 7);
		case CLASS_H:
			return this.isSupportedByTerminal(22, 4);
		case CLASS_I:
			return this.isSupportedByTerminal(25, 3);
		case CLASS_J:
			return this.isSupportedByTerminal(22, 6);
		case CLASS_K:
			return this.isSupportedByTerminal(30, 3);
		case CLASS_L:
			return this.isSupportedByTerminal(30, 5);
		case CLASS_M:
			return this.isSupportedByTerminal(25, 6);
		case CLASS_N:
			return this.isSupportedByTerminal(23, 5);
		case CLASS_O:
			return this.isSupportedByTerminal(30, 7);
		case CLASS_P:
			return this.isSupportedByTerminal(23, 8);
		default:
			return false;
		}
	}

}
